package com.ohuang.launcher;

import android.content.ComponentName;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.util.Log;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ActivityInterceptor {
    public static final String TAG = "ActivityInterceptor";
    public static final String[] packages = {"com.tencent.android.qqdownloader",
            "com.qihoo.appstore",
            "com.baidu.appsearch",
            "com.xiaomi.market",
            "com.huawei.appmarket",
            "com.android.vending",
            "com.meizu.mstore",
            "com.oppo.market",
            "com.bbk.appstore",
            "com.sogou.androidtool",
            "com.sec.android.app.samsungapps",
            "com.lenovo.leos.appstore",
            "zte.com.market"
    };

    public static final String[] schemes = {"mimarket", "tmast","market","samsungapps","appmarket","oppomarket","vivomarket","zjmobile","kwai"};

    public static boolean isHooked = false;

    public static Object mObject=null;

    public synchronized static void hook() {
        if (isHooked) {
            return;
        }
        isHooked = true;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            try {
                Class<?> aClass = Class.forName("android.app.ActivityTaskManager");
                Field field_IActivityTaskManagerSingleton = aClass.getDeclaredField("IActivityTaskManagerSingleton");
                field_IActivityTaskManagerSingleton.setAccessible(true);
                Object iActivityTaskManagerSingleton = field_IActivityTaskManagerSingleton.get(null);

                Class<?> aClass_Singleton = Class.forName("android.util.Singleton");
                Field field_mInstance = aClass_Singleton.getDeclaredField("mInstance");
                field_mInstance.setAccessible(true);
                Method method_get = aClass_Singleton.getDeclaredMethod("get");
                Object mInstant = method_get.invoke(iActivityTaskManagerSingleton);
                mObject=mInstant;
                Class<?> aClass_IActivityTaskManager = Class.forName("android.app.IActivityTaskManager");
                Object mInstantProxy = Proxy.newProxyInstance(aClass_IActivityTaskManager.getClassLoader(), new Class[]{aClass_IActivityTaskManager}, new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                        if ("startActivity".equals(method.getName())) {
                            Intent intent = (Intent) args[3];
                            if (isInterceptor(intent)) {
                                return 0;
                            }
                        }
                        return method.invoke(mInstant, args);
                    }
                });
                field_mInstance.set(iActivityTaskManagerSingleton, mInstantProxy);

            } catch
            (ClassNotFoundException | IllegalAccessException | NoSuchMethodException | InvocationTargetException | NoSuchFieldException
                            e) {
                e.printStackTrace();
            }
        } else {
            try {
                Class<?> aClass = Class.forName("android.app.ActivityManager");
                Field field_IActivityTaskManagerSingleton = aClass.getDeclaredField("IActivityManagerSingleton");
                field_IActivityTaskManagerSingleton.setAccessible(true);
                Object iActivityTaskManagerSingleton = field_IActivityTaskManagerSingleton.get(null);

                Class<?> aClass_Singleton = Class.forName("android.util.Singleton");
                Field field_mInstance = aClass_Singleton.getDeclaredField("mInstance");
                field_mInstance.setAccessible(true);
                Method method_get = aClass_Singleton.getDeclaredMethod("get");
                Object mInstant = method_get.invoke(iActivityTaskManagerSingleton);
                mObject=mInstant;
                Class<?> aClass_IActivityManager = Class.forName("android.app.IActivityManager");
                Object mInstantProxy = Proxy.newProxyInstance(aClass_IActivityManager.getClassLoader(), new Class[]{aClass_IActivityManager}, new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                        if ("startActivity".equals(method.getName())) {
                            Intent intent = (Intent) args[2];
                            if (isInterceptor(intent)) {
                                return 0;
                            }
                        }
                        return method.invoke(mInstant, args);
                    }
                });

                field_mInstance.set(iActivityTaskManagerSingleton, mInstantProxy);

            } catch
            (ClassNotFoundException | IllegalAccessException | NoSuchMethodException | InvocationTargetException | NoSuchFieldException
                            e) {
                e.printStackTrace();
            }

        }

    }

    public synchronized static void unHook(){
        if (isHooked&&mObject!=null){
            isHooked=false;

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                try {
                    Class<?> aClass = Class.forName("android.app.ActivityTaskManager");
                    Field field_IActivityTaskManagerSingleton = aClass.getDeclaredField("IActivityTaskManagerSingleton");
                    field_IActivityTaskManagerSingleton.setAccessible(true);
                    Object iActivityTaskManagerSingleton = field_IActivityTaskManagerSingleton.get(null);

                    Class<?> aClass_Singleton = Class.forName("android.util.Singleton");
                    Field field_mInstance = aClass_Singleton.getDeclaredField("mInstance");
                    field_mInstance.setAccessible(true);
                    field_mInstance.set(iActivityTaskManagerSingleton, mObject);

                } catch
                (ClassNotFoundException | IllegalAccessException | NoSuchFieldException
                                e) {
                    e.printStackTrace();
                }
            } else {
                try {
                    Class<?> aClass = Class.forName("android.app.ActivityManager");
                    Field field_IActivityTaskManagerSingleton = aClass.getDeclaredField("IActivityManagerSingleton");
                    field_IActivityTaskManagerSingleton.setAccessible(true);
                    Object iActivityTaskManagerSingleton = field_IActivityTaskManagerSingleton.get(null);
                    Class<?> aClass_Singleton = Class.forName("android.util.Singleton");
                    Field field_mInstance = aClass_Singleton.getDeclaredField("mInstance");
                    field_mInstance.setAccessible(true);
                    field_mInstance.set(iActivityTaskManagerSingleton, mObject);

                } catch
                (ClassNotFoundException | IllegalAccessException | NoSuchFieldException
                                e) {
                    e.printStackTrace();
                }
            }
        }
    }


    private static boolean isInterceptor(Intent intent) {
        Log.e(TAG, "isInterceptor: " + intent);
        try {
            ComponentName component = intent.getComponent();
            String packageName=null;
            if (component!=null) {
                 packageName = component.getPackageName();
            }else {
                 packageName= intent.getPackage();
            }
                Log.e(TAG, "isInterceptor: packageName="+packageName );
                for (int i = 0; i < packages.length; i++) {
                    if (packages[i].equals(packageName)) {
                        Log.e(TAG, "isInterceptor: true" );
                        return true;
                    }
                }

        } catch (Exception e) {
            e.printStackTrace();
        }

        try {
            Uri data = intent.getData();
            if (data != null) {
                String scheme = data.getScheme();
                Log.e(TAG, "isInterceptor: scheme="+scheme );
                for (int i = 0; i < schemes.length; i++) {
                    if (schemes[i].equals(scheme)) {
                        Log.e(TAG, "isInterceptor: true" );
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.e(TAG, "isInterceptor: false" );
        return false;
    }
}
